package com.ziyueyuwen.xiniao.module;

import com.suyeer.basic.util.LogUtil;
import com.ziyueyuwen.xiniao.base.SpringFactory;
import com.ziyueyuwen.xiniao.bean.user.TbAuthInfo;
import com.ziyueyuwen.xiniao.dao.TbAuthInfoMapper;
import com.ziyueyuwen.xiniao.util.CacheUtil;

import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import static com.ziyueyuwen.xiniao.util.ConstUtil.MC_KEY_AUTH_INFO_INIT_TIME;

/**
 * @author jun 2018/12/4
 */
public class AuthInfoCache {

    private static class LazyHolder {
        private static final AuthInfoCache OUR_INSTANCE = new AuthInfoCache();
    }

    public static AuthInfoCache getInstance() {
        return LazyHolder.OUR_INSTANCE;
    }

    private AuthInfoCache() {
    }

    private Long initTime = System.currentTimeMillis();

    private TbAuthInfoMapper tbAuthInfoMapper = SpringFactory.getBean("tbAuthInfoMapper");

    /**
     * 对应的权限点列表
     */
    private final ConcurrentHashMap<String, HashSet<String>> uriPointMap = new ConcurrentHashMap<>();

    /**
     * 权限点对应的 uri 列表
     */
    private final ConcurrentHashMap<String, HashSet<String>> pointUriMap = new ConcurrentHashMap<>();

    private void init() {
        try {
            Boolean isNeedInit = CacheUtil.isNeedInit(MC_KEY_AUTH_INFO_INIT_TIME, initTime, uriPointMap.isEmpty());
            if (isNeedInit) {
                List<TbAuthInfo> list = tbAuthInfoMapper.listAll();
                String uri, point;
                for (TbAuthInfo t : list) {
                    uri = t.getAuthUri().trim();
                    point = t.getAuthPoint().trim();
                    if (!uriPointMap.containsKey(uri)) {
                        uriPointMap.put(uri, new HashSet<>());
                    }
                    if (!pointUriMap.containsKey(point)) {
                        pointUriMap.put(point, new HashSet<>());
                    }
                    uriPointMap.get(uri).add(point);
                    pointUriMap.get(point).add(uri);
                }
                LogUtil.info("权限列表缓存初始化完成!");
            }
        } catch (Exception e) {
            LogUtil.error("初始化权限列表失败: {}!", e.getMessage());
        }
    }

    public HashSet<String> getWhiteUri() {
        init();
        return pointUriMap.get("whiteUri");
    }

    public Boolean isPermission(List<String> userAuthList, String uri) {
        try {
            init();
            if (!uriPointMap.containsKey(uri)) {
                return true;
            }
            userAuthList.retainAll(uriPointMap.get(uri));
            return userAuthList.size() > 0;
        } catch (Exception e) {
            LogUtil.error("判断权限失败, 默认无权限: {}", e.getMessage());
            return false;
        }
    }
}
